package com.xinxin.socket.encoder;

import com.xinxin.socket.constant.CommandId;
import com.xinxin.socket.msg.NetMsg;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;

/**
 * @author ys
 * @date 2020/8/11
 */
public class NetMsgSeqEncoder extends MessageToByteEncoder<NetMsg> {

    private int seq = 0;

    @Override
    protected void encode(ChannelHandlerContext ctx, NetMsg msg, ByteBuf out) {
        /*
        此handler用来处理服务器推送seq
        当cmdId类型不是resp的时候，递增seq并替换消息内默认的0

        实际上由于此handler在pipeline的末尾
        resp类型的消息是通过ctx发出的，从中间开始，不会触及此handler
        而服务器主动推送的是通过channel发出的，才会触发此handler
        所以理论上一旦触及此handler都不会跳过if内代码
         */
        int cmdId = msg.getCmdId();
        if (cmdId != CommandId.SYS_HEART_REPLY
                && cmdId != CommandId.USER_LOGIN) {
            msg.setSeq(seq++);
        }

        /*
        向默认的NetMsgEncoder传递

        由于未向out写入内容，所以方法返回后会在MessageToByteEncoder向下一个Encoder传入一个Unpooled.EMPTY_BUFFER
        此时必须手动将NetMsg传递给下一个Encoder
         */
        ctx.writeAndFlush(msg);
    }
}
